<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>节点的动画</title>
  </head>

  <body>
    <div id="mountNode"></div>
    <script src="../build/g6.js"></script>
    <script>
      const Util = G6.Util;
      const data = {
        nodes: [
          {
            id: 'node1',
            x: 100,
            y: 100,
            shape: 'circle-animate',
            size: 20,
            label: '图形动画',
            labelCfg: {
              position: 'bottom',
            },
          },
          {
            id: 'node2',
            x: 300,
            y: 200,
            shape: 'background-animate',
            color: '#b5b5b5',
            size: 20,
            label: '背景动画',
            labelCfg: {
              position: 'bottom',
            },
          },
          {
            id: 'node3',
            x: 400,
            y: 100,
            size: [40, 40],
            shape: 'inner-animate',
            img:
              '',
            label: 'rect',
            labelCfg: {
              position: 'bottom',
            },
          },
          {
            id: 'node4',
            x: 300,
            y: 400,
            shape: 'rect',
            label: 'rect',
            labelCfg: {
              position: 'bottom',
            },
          },
        ],
        edges: [
          {
            source: 'node1',
            target: 'node2',
          },
          {
            source: 'node3',
            target: 'node2',
          },
          {
            source: 'node2',
            target: 'node4',
          },
        ],
      };

      // 放大、变小动画
      G6.registerNode(
        'circle-animate',
        {
          afterDraw(cfg, group) {
            const shape = group.get('children')[0];
            shape.animate(
              {
                repeat: true,
                onFrame(ratio) {
                  const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
                  return {
                    r: cfg.size / 2 + diff,
                  };
                },
              },
              3000,
              'easeCubic',
            );
          },
        },
        'circle',
      );

      G6.registerNode(
        'background-animate',
        {
          afterDraw(cfg, group) {
            const r = cfg.size / 2;
            const back1 = group.addShape('circle', {
              zIndex: -3,
              attrs: {
                x: 0,
                y: 0,
                r,
                fill: cfg.color,
                opacity: 0.6,
              },
            });
            const back2 = group.addShape('circle', {
              zIndex: -2,
              attrs: {
                x: 0,
                y: 0,
                r,
                fill: cfg.color,
                // 为了显示清晰，随意设置了颜色
                opacity: 0.6,
              },
            });

            const back3 = group.addShape('circle', {
              zIndex: -1,
              attrs: {
                x: 0,
                y: 0,
                r,
                fill: cfg.color,
                opacity: 0.6,
              },
            });
            group.sort(); // 排序，根据zIndex 排序
            back1.animate(
              {
                // 逐渐放大，并消失
                r: r + 10,
                opacity: 0.1,
                repeat: true, // 循环
              },
              3000,
              'easeCubic',
              null,
              0,
            ); // 无延迟
            back2.animate(
              {
                // 逐渐放大，并消失
                r: r + 10,
                opacity: 0.1,
                repeat: true, // 循环
              },
              3000,
              'easeCubic',
              null,
              1000,
            ); // 1 秒延迟
            back3.animate(
              {
                // 逐渐放大，并消失
                r: r + 10,
                opacity: 0.1,
                repeat: true, // 循环
              },
              3000,
              'easeCubic',
              null,
              2000,
            ); // 2 秒延迟
          },
        },
        'circle',
      );

      G6.registerNode(
        'inner-animate',
        {
          afterDraw(cfg, group) {
            const size = cfg.size;
            const width = size[0] - 12;
            const height = size[1] - 12;
            const image = group.addShape('image', {
              attrs: {
                x: -width / 2,
                y: -height / 2,
                width: width,
                height: height,
                img: cfg.img,
              },
            });
            image.animate(
              {
                onFrame(ratio) {
                  const matrix = Util.mat3.create();
                  const toMatrix = Util.transform(matrix, [['r', ratio * Math.PI * 2]]);
                  return {
                    matrix: toMatrix,
                  };
                },
                repeat: true,
              },
              3000,
              'easeCubic',
            );
          },
        },
        'rect',
      );

      const graph = new G6.Graph({
        container: 'mountNode',
        width: 1000,
        height: 600,
      });
      graph.data(data);
      graph.render();
    </script>
  </body>
</html>
